<?php
namespace app\api\logic;

use app\api\consDir\ErrorConst;
use app\api\services\CouponService;
use app\common\libs\Singleton;
use app\common\models\Coupon;
use app\common\models\CouponMember;
use app\common\models\Member\MemberCoupon;
use app\common\utils\CommonUtil;
use app\common\utils\RedLock;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

/**
 * 优惠券模块
 * Class MemberLogic
 * @package app\api\logic
 */
class CouponLogic extends BaseLogic
{
    use Singleton;

    /**
     * 旧的方法，在优惠券功能上线前需要删除只
     * @param $type
     * @param $page
     * @param $pageSize
     * @return array [type] [description]
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function couponList($type, $page, $pageSize): array
    {
        switch ($type) {
            //1未使用 2已使用 3过期
            case 1:
                $where = [
                    ['user_id', '=', $this->userinfo->id],
                    ['status', '=', 0],
                    ['end_at', '>', date('Y-m-d H:i:s')],
                    ['deleted', '=', 0],
                ];
                break;
            case 2:
                $where = [
                    ['user_id', '=', $this->userinfo->id],
                    ['status', '=', 1],
                    ['deleted', '=', 0],
                ];
                break;
            default:
                $where = [
                    ['user_id', '=', $this->userinfo->id],
                    ['end_at', '<=', date('Y-m-d H:i:s')],
                    ['deleted', '=', 0],
                ];
        }

        $couponList = MemberCoupon::getInstance()
            ->where($where)
            ->field('id,title,type,full_amount,amount,coupon_type,end_at,create_at')
            ->limit(($page - 1) * $pageSize, $pageSize)
            ->order('id desc')
            ->select();
        if (empty($couponList)) {
            return [];
        }
        $couponList = $couponList->toArray();
        return ['rows' => $couponList];
    }

    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function myCouponList($status, $page, $pageSize): array
    {
        switch ($status) {
            //1未使用 2已使用 3过期
            case 1:
                $where = [
                    ['user_id', '=', $this->userinfo->id],
                    // 0未使用 1已使用
                    ['status', '=', 0],
                    ['end_time', '>', date('Y-m-d H:i:s')],
                    ['deleted', '=', 0],
                ];
                break;
            case 2:
                $where = [
                    ['user_id', '=', $this->userinfo->id],
                    // 0未使用 1已使用
                    ['status', '=', 1],
                    ['deleted', '=', 0],
                ];
                break;
            default:
                $where = [
                    ['user_id', '=', $this->userinfo->id],
                    // 0未使用 1已使用
                    ['status', '=', 0],
                    ['end_time', '<=', date('Y-m-d H:i:s')],
                    ['deleted', '=', 0],
                ];
        }

        $couponList = CouponMember::getInstance()
            ->where($where)
            ->field('*')
            ->page($page, $pageSize)
            ->order('id desc')
            ->select();
        if (empty($couponList)) {
            return [];
        }
        $couponList = $couponList->toArray();
        return ['rows' => $couponList];
    }

    /**
     * 可用优惠券
     * @param $shopId
     * @param $page
     * @param $pageSize
     * @param int $goodsId
     * @return array [type]         [description]
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function available($shopId, $page, $pageSize, $goodsId, $source): array
    {
        $where = [
            ['deleted', '=', 0],
            // 状态 0 未开始 1 进行中 2 已结束
            ['status', '=', 1],
            ['shop_id', 'in', [0, (int) $shopId]],
        ];
        $field = [
            'id',
            'coupon_title',
            'coupon_type',
            'reduce_price',
            'discount',
            'min_price',
            'expire_type',
            'expire_day',
            'start_time',
            'end_time',
            'use_scene',
            'apply_range',
            'total_num',
            'receive_limit',
            'receive_num',
            'sort',
            'remark',
            'auto_release',
            'multiple',
            'multiple_other',
            'shop_id',
            'create_at',
        ];
        $items = Coupon::getInstance()
            ->where($where)
            ->field($field)
            ->page($page, $pageSize)
            ->order('sort desc, id desc')
            ->select()->toArray();
        // echo Coupon::getlastsql();exit;
        if (empty($items)) {
            return [];
        }

        // use_scene 使用场景:  10只能社区经营者使用
        //expire_type 到期类型(10领取后生效 20固定时间 30 长期有效)
        $rows = [];
        // received 领券的张数 0 未领取
        $uid = $this->userinfo->id;

        $receivedMap = [];
        if ($uid > 0) {
            $ids   = array_column($items, 'id');
            $where = [
                ['deleted', '=', 0],
                ['user_id', '=', $uid],
                ['coupon_id', 'in', $ids],
            ];
            $receivedMap = CouponMember::getInstance()->where($where)
                ->group('coupon_id')
                ->column('count(coupon_id)', 'coupon_id');
            // echo CouponMember::getInstance()->getlastsql();exit;
            // var_dump($receivedMap);exit;
        }
        $shopType = $shopId > 0?\think\facade\Db::table('member_shop')
            ->where('id', $shopId)
            ->value('shop_type') : 3;
        // var_dump($uid);exit;
        // auto_release 是否允许直接领取 1 自动领取 2 手动领取'
        // 适用范围 10全部商品 20指定商品 30排除商品
        foreach ($items as $vo) {
            $useScene   = $vo['useScene'];
            $expireType = $vo['expireType'];
            $applyRange = $vo['applyRange'];

            // if ($vo['id'] == 14) {
            //     var_dump([
            //         'useScene'   => $useScene,
            //         'expireType' => $expireType,
            //         'applyRange' => $applyRange,
            //     ]);exit;
            // }
            // 使用场景:  10只能社区经营者使用
            if ($useScene == 10) {
                continue;
            }
            if ($expireType == 20) {
                $end_time = strtotime($vo['endTime']);
                if ($end_time < time()) {
                    continue;
                }
            }
            if ($applyRange != 10) {
                $checked = CouponService::getInstance()->checkApplyRange(
                    $vo['id'],
                    $source,
                    $goodsId,
                    $included = $applyRange == 20 ? 1 : 0,
                );
                // if ($vo['id'] == 14) {
                //     var_dump($checked, $vo['id'], $source, $goodsId, $applyRange);exit;
                // }
                if ( ! $checked) {
                    continue;
                }
            }
            $vo['shopType'] = $vo['shopId'] > 0 ? $shopType : 3;
            $vo['received'] = $receivedMap[$vo['id']] ?? 0;

            if ($vo['autoRelease'] == 1 && $uid > 0 && $vo['received'] == 0) {
                $res = CouponService::getInstance()->autoRelease($uid, $vo);
                if ( ! empty($res['id'])) {
                    $vo['received'] = 1;
                }
            }
            $rows[] = $vo;
            // var_dump($applyRange);exit;
        }
        return ['rows' => $rows];
    }

    /**
     * 领取优惠券
     * @param  [type] $couponId [description]
     * @return array [type]           [description]
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function receive($couponId, $goodsId, $source): array
    {
        if ( ! RedLock::getInstance()->lock('coupon_receive:' . $this->userinfo->id, 2)) {
            CommonUtil::throwException(
                ErrorConst::FREQUENT_ERROR,
                ErrorConst::FREQUENT_ERROR_MSG
            );
        }
        $where = [
            ['deleted', '=', 0],
            // 状态 0 未开始 1 进行中 2 已结束
            ['status', '=', 1],
            ['id', '=', (int) $couponId],
        ];
        $vo = Coupon::getInstance()
            ->where($where)
            ->find();
        if (empty($vo)) {
            CommonUtil::throwException(
                ErrorConst::QUERY_NOT_EXIST,
                ErrorConst::QUERY_NOT_EXIST_MSG);
        }
        $vo = $vo->toArray();

        // use_scene 使用场景:  10只能社区经营者使用
        $useScene = $vo['useScene'];
        if ($useScene == 10) {
            CommonUtil::throwException(
                ErrorConst::QUERY_NOT_EXIST,
                '不允许领取');
        }

        // 适用范围 10全部商品 20指定商品 30排除商品
        $applyRange = $vo['applyRange'];
        if ($applyRange != 10) {
            $checked = CouponService::getInstance()->checkApplyRange(
                $vo['id'],
                $source,
                $goodsId,
                $included = $applyRange == 20 ? 1 : 0,
            );
            // var_dump($checked);exit;
            if ($checked == false) {
                CommonUtil::throwException(
                    ErrorConst::COUPON_ERROR,
                    '优惠券使用范围受限');
            }
        }

        $vo['shopType'] = $this->getShopType($source, $goodsId);

        $uid = $this->userinfo->id;
        // var_dump($uid, $vo);exit;
        $res = CouponService::getInstance()->autoRelease($uid, $vo);

        if ( ! empty($res['error'])) {
            CommonUtil::throwException(
                $res['code'],
                $res['error']);
        }
        return ['id' => $res['id']];
    }

    /**
     * 商品来源：1 日兮香商品(商家/平台自建商品) 2 怡亚通商品
     * @param  [type] $source  [description]
     * @param  [type] $goodsId [description]
     * @return [type]        shopType 3 店铺ID为空的情况； 1线下 2线上'
     */
    private function getShopType($source, $goodsId)
    {
        if ($source != 1) {
            return 3;
        }
        $shopId = \think\facade\Db::table('goods')
            ->where('id', $goodsId)
            ->value('shop_id');
        return $shopId > 0?\think\facade\Db::table('member_shop')
            ->where('id', $shopId)
            ->value('shop_type') : 3;
    }

    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function myCouponMember($shopId, $page, $pageSize, $goodsId, $source): array
    {
        $where = [
            ['user_id', '=', $this->userinfo->id],
            ['deleted', '=', 0],
            ['status', '=', 0],
            ['end_time', '>=', date('Y-m-d H:i:s')],
        ];
        $whereOr = [];
        //线上线下
        if ($source == 1) {
            $whereOr[] = ['shop_id', '=', $shopId];
            $whereOr[] = ['shop_id', '=', 0];
        }
        //供应链只显示平台优惠券
        if ($source == 2) {
            $where[] = ['shop_id', '=', 0];
        }
        $list = CouponMember::getInstance()->where($where)->where(function ($query) use ($whereOr) {
            $query->whereOr($whereOr);
        })
            ->page($page, $pageSize)
            ->select();
        $vo = [];
        foreach ($list as $v) {
            if ($v['applyRange'] != 10) {
                $checked = CouponService::getInstance()->checkApplyRange(
                    $v['couponId'],
                    $source,
                    $goodsId,
                    $v['applyRange'] == 20 ? 1 : 0
                );
                if ( ! $checked) {
                    continue;
                }
            }
            $vo[] = $v;
        }
        return $vo;
    }

}
